﻿using IM.Easy.AuthorizationServices.Dtos;
using IM.Easy.AuthorizationServices.IServices;
using IM.Easy.Core.AppContext;
using IM.Easy.Core.Constants;
using IM.Easy.Core.Enums;
using IM.Easy.Core.Extensions;
using IM.Easy.Core.Options;
using IM.Easy.Core.Result;
using IM.Easy.Core.Security;
using IM.Easy.Core.Services;
using IM.Easy.Core.Utils;
using IM.Easy.Entity.System;
using Mapster;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;


namespace IM.Easy.AuthorizationServices.Services
{

    public class IdentityService(ISqlSugarClient db) : AppServices(db), IIdentityService
    {

        /// <summary>
        /// 获取登录用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ApiResult<LoginUser> GetLoginUser(LoginInput input)
        {
            var query = Db.Queryable<SysUser>();
            var user = query.First(s => s.UserName == input.UserName);
            // 判断用户是否存在，密码是否正确
            if (user == null || !Sha256Hash.ValidateHash(input.Password, user.Password))
            {
                return ApiResult<LoginUser>.Failure("用户名或密码错误", ResultCode.BusinessLogicError);
            }
            if (!user.IsActive)
            {
                return ApiResult<LoginUser>.Failure("账户未启用", ResultCode.BusinessLogicError);
            }
            var loginUser = user.Adapt<LoginUser>();
            loginUser.ClientId = ImApp.Current.GetClientId(); // App.HttpContext.Connection.Id;
            return ApiResult<LoginUser>.Success(loginUser);
        }

        /// <summary>
        /// 绑定登录用户的角色
        /// </summary>
        /// <returns></returns>
        public void BindRoles(LoginUser user)
        {
            var roles = new List<LoginUserRole>();

            if (user.IsSuperAdmin)
            {
                roles.Add(new LoginUserRole()
                {
                    Code = "superAdmin",
                    Name = "超级管理员",
                    Perms = "*:*:*",
                });
            }
            else
            {
                //roles = Db.Queryable<SysRole>()
                // .InnerJoin<SysUserRole>((r, ur) => r.Id == ur.RoleId)
                // .Where((r, ur) => ur.UserId == user.Id)
                // .Select((r, ur) => r)
                // .ToList()
                // .Adapt<List<LoginUserRole>>();
            }
            user.Roles = roles;
        }

        /// <summary>
        /// 绑定登录用户的权限
        /// </summary>
        /// <returns></returns>
        public void BindPermission(LoginUser user)
        {
            //var perms = new List<string>();
            //if (user.IsSuperAdmin)
            //    perms.Add("*:*:*");
            //else
            //{
            //    var menus = Db.Queryable<SysMenu, SysRoleMenu, SysUserRole, SysRole>((m, rm, ur, r) => new JoinQueryInfos(
            //           JoinType.Left, m.Id == rm.MenuId,
            //           JoinType.Left, rm.RoleId == ur.RoleId,
            //           JoinType.Left, ur.RoleId == r.Id
            //   ))
            //   .Where((m, rm, ur, r) => ur.UserId == user.Id)
            //   .Select((m, rm, ur, r) => m).ToList();
            //    var menuList = menus.Where(f => !string.IsNullOrEmpty(f.Perms));

            //    perms = menuList.Select(x => x.Perms).Distinct().ToList();
            //}
            //user.Perms = perms;
        }

        /// <summary>
        /// 颁发token
        /// </summary>
        /// <returns></returns>
        public string IssureAccessToken(LoginUser user)
        {
            var payload = new Dictionary<string, object>
            {
                {ClaimTypes.PrimarySid,user.Id },
                { ClaimTypes.NameIdentifier, user.UserName },
                { ClaimTypes.Name, user.UserName },
                { ClaimConstTypes.ClientId, user.ClientId },
                {ClaimConstTypes.Provider,user.Provider }
            };

            // 生成 token
            var accessToken = JwtEncryption.EncryptToken(payload);

            //写入缓存
            return accessToken;
        }
    }
}
